/**
 * @fileOverview The "listblock" plugin.
 */
VED.plugins.add( 'listblock', {
   requires: 'panel',

   onLoad: function() {
      var list = VED.addTemplate( 'panel-list', '<ul role="presentation" class="ved_panel_list">{items}</ul>' ),
         listItem = VED.addTemplate( 'panel-list-item', '<li id="{id}" class="ved_panel_listItem" role=presentation>' +
            '<a id="{id}_option" _ved_focus=1 hidefocus=true' +
               ' title="{title}"' +
               ' href="javascript:void(\'{val}\')" ' +
               ' {onclick}="VED.tools.callFunction({clickFn},\'{val}\'); return false;"' + // #188
                  ' role="option">' +
               '{text}' +
            '</a>' +
            '</li>' ),
         listGroup = VED.addTemplate( 'panel-list-group', '<h1 id="{id}" class="ved_panel_grouptitle" role="presentation" >{label}</h1>' );

      VED.ui.panel.implement({
         addListBlock: function( name, definition ) {
            return this.addBlock( name, new VED.ui.listBlock( this.getHolderElement(), definition ) );
         }
      });

      VED.ui.listBlock = VED.ui.panel.block.extend({

         initialize: function( blockHolder, blockDefinition ) {
            blockDefinition = blockDefinition || {};

            var attribs = blockDefinition.attributes || ( blockDefinition.attributes = {} );
            ( this.multiSelect = !!blockDefinition.multiSelect ) && ( attribs[ 'aria-multiselectable' ] = true );
            // Provide default role of 'listbox'.
            !attribs.role && ( attribs.role = 'listbox' );

            // Call the base contructor.
            this.parent.apply( this, arguments );

            // Set the proper a11y attributes.
            this.element.setAttribute( 'role', attribs.role );

            var keys = this.keys;
            keys[ 40 ] = 'next'; // ARROW-DOWN
            keys[ 9 ] = 'next'; // TAB
            keys[ 38 ] = 'prev'; // ARROW-UP
            keys[ VED.SHIFT + 9 ] = 'prev'; // SHIFT + TAB
            keys[ 32 ] = VED.env.ie ? 'mouseup' : 'click'; // SPACE
            VED.env.ie && ( keys[ 13 ] = 'mouseup' ); // Manage ENTER, since onclick is blocked in IE (#8041).

            this._ = {
               pendingHtml: [],
               pendingList: [],
               items: {},
               groups: {}
            };

            this._.close = function() {
               if ( this._.started ) {
                  var output = list.output({ items: this._.pendingList.join( '' ) } );
                  this._.pendingList = [];
                  this._.pendingHtml.push( output );
                  delete this._.started;
               }
            }.bind(this);

            this._.getClick = function() {
               if ( !this._.click ) {
                  this._.click = VED.tools.addFunction( function( value ) {
                     var marked = this.toggle( value );
                     if ( this.onClick )
                        this.onClick( value, marked );
                  }, this );
               }
               return this._.click;
            }.bind(this);

         },
/*
         _: {
            close: function() {
               if ( this._.started ) {
                  var output = list.output({ items: this._.pendingList.join( '' ) } );
                  this._.pendingList = [];
                  this._.pendingHtml.push( output );
                  delete this._.started;
               }
            },

            getClick: function() {
               if ( !this._.click ) {
                  this._.click = VED.tools.addFunction( function( value ) {
                     var marked = this.toggle( value );
                     if ( this.onClick )
                        this.onClick( value, marked );
                  }, this );
               }
               return this._.click;
            }
         },
*/
         add: function( value, html, title ) {
            var id = VED.tools.getNextId();

            if ( !this._.started ) {
               this._.started = 1;
               this._.size = this._.size || 0;
            }

            this._.items[ value ] = id;

            var data = {
               id: id,
               val: value,
               onclick: VED.env.ie ? 'onclick="return false;" onmouseup' : 'onclick',
               clickFn: this._.getClick(),
               title: title || value,
               text: html || value
            };

            this._.pendingList.push( listItem.output( data ) );
         },

         startGroup: function( title ) {
            this._.close();

            var id = VED.tools.getNextId();

            this._.groups[ title ] = id;

            this._.pendingHtml.push( listGroup.output({ id: id, label: title } ) );
         },

         commit: function() {
            this._.close();
            this.element.appendHtml( this._.pendingHtml.join( '' ) );
            delete this._.size;

            this._.pendingHtml = [];
         },

         toggle: function( value ) {
            var isMarked = this.isMarked( value );

            if ( isMarked )
               this.unmark( value );
            else
               this.mark( value );

            return !isMarked;
         },

         hideGroup: function( groupTitle ) {
            var group = this.element.getDocument().getById( this._.groups[ groupTitle ] ),
               list = group && group.getNext();

            if ( group ) {
               group.setStyle( 'display', 'none' );

               if ( list && list.getName() == 'ul' )
                  list.setStyle( 'display', 'none' );
            }
         },

         hideItem: function( value ) {
            this.element.getDocument().getById( this._.items[ value ] ).setStyle( 'display', 'none' );
         },

         showAll: function() {
            var items = this._.items,
               groups = this._.groups,
               doc = this.element.getDocument();

            for ( var value in items ) {
               doc.getById( items[ value ] ).setStyle( 'display', '' );
            }

            for ( var title in groups ) {
               var group = doc.getById( groups[ title ] ),
                  list = group.getNext();

               group.setStyle( 'display', '' );

               if ( list && list.getName() == 'ul' )
                  list.setStyle( 'display', '' );
            }
         },

         mark: function( value ) {
            if ( !this.multiSelect )
               this.unmarkAll();

            var itemId = this._.items[ value ],
               item = this.element.getDocument().getById( itemId );
            item.addClass( 'ved_selected' );

            this.element.getDocument().getById( itemId + '_option' ).setAttribute( 'aria-selected', true );
            this.onMark && this.onMark( item );
         },

         unmark: function( value ) {
            var doc = this.element.getDocument(),
               itemId = this._.items[ value ],
               item = doc.getById( itemId );

            item.removeClass( 'ved_selected' );
            doc.getById( itemId + '_option' ).removeAttribute( 'aria-selected' );

            this.onUnmark && this.onUnmark( item );
         },

         unmarkAll: function() {
            var items = this._.items,
               doc = this.element.getDocument();

            for ( var value in items ) {
               var itemId = items[ value ];

               doc.getById( itemId ).removeClass( 'ved_selected' );
               doc.getById( itemId + '_option' ).removeAttribute( 'aria-selected' );
            }

            this.onUnmark && this.onUnmark();
         },

         isMarked: function( value ) {
            return this.element.getDocument().getById( this._.items[ value ] ).hasClass( 'ved_selected' );
         },

         focus: function( value ) {
            this._.focusIndex = -1;

            if ( value ) {
               var selected = this.element.getDocument().getById( this._.items[ value ] ).getFirst();

               var links = this.element.getElementsByTag( 'a' ),
                  link,
                  i = -1;

               while ( ( link = links.getItem( ++i ) ) ) {
                  if ( link.equals( selected ) ) {
                     this._.focusIndex = i;
                     break;
                  }
               }

               setTimeout( function() {
                  selected.focus();
               }, 0 );
            }
         }
      });
   }
});






